package Client;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import ServerApp.IServer;
import ServerApp.Meeting;
import ServerApp.Tools;
import ServerApp.User;

import com.toedter.calendar.JCalendar;

@SuppressWarnings("serial")
public class HauptFenster extends JFrame {

	private IServer server;
	private JCalendar cal;
	private Date selectedDate;
	private ArrayList<Meeting> meetings;
	private User user;
	private JLabel logo;
	private JLabel lUser = new JLabel();
	private JButton bnLogOut = new JButton();
	private JButton bnAddUser = new JButton("Add User");
	private JPanel panelCal = new JPanel();
	private JPanel panelLogout = new JPanel();
	private JSplitPane splitPane;
	private JTabbedPane tabPane = new JTabbedPane();
	@SuppressWarnings("rawtypes")
	private JList listDayMeetings = new JList();
	@SuppressWarnings("rawtypes")
	private JList listAllMeetings = new JList();
	@SuppressWarnings("rawtypes")
	private DefaultListModel lm1 = new DefaultListModel();
	@SuppressWarnings("rawtypes")
	private DefaultListModel lm2 = new DefaultListModel();
	private JEditorPane meetingDetails = new JEditorPane();
	private JButton bnAddMeeting = new JButton("Add Meeting");
	private JButton bnDeleteMeeting = new JButton("Delete Meeting");
	private Meeting selectedMeeting = null;
	
	public HauptFenster(IServer server, User user) {
		super("Meeting scheduler");
		this.user = user;
		this.server = server;
		// this.meetings = meetings;
		InitializeComponent();
		bnAddMeeting.setEnabled(user.getPermission());
//		bnDeleteMeeting.setEnabled(user.getPermission());
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void InitializeComponent() {

		bnDeleteMeeting.setEnabled(false);
		lUser.setText("Logged in as: " + user.getName());
		bnLogOut.setText("Log Out");
		bnLogOut.setPreferredSize(new Dimension(80, 15));
		bnLogOut.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				bLogOutAction();
			}
		});
		bnAddUser.setPreferredSize(new Dimension(120, 15));
		bnAddUser.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				bnAddUserAction();
			}
		});
		panelLogout.add(lUser);
		panelLogout.add(bnLogOut);
		panelLogout.setBackground(new Color(0, 0, 0, 0));
		if (user.getName().equals("admin"))
			panelLogout.add(bnAddUser);
		// Create the time/date Logout panel
		JPanel timePanel = new JPanel();
		timePanel.setLayout(new GridBagLayout());
		ImageIcon icon = createImageIcon("logo.png");
		logo = new JLabel(icon);
		logo.setLayout(new GridBagLayout());
		logo.add(panelLogout, new GridBagConstraints(0, 0, 1, 1, 1.1, 1.0,
				GridBagConstraints.LAST_LINE_START, GridBagConstraints.NONE,
				new Insets(0, 0, 0, 0), 0, 0));
		timePanel.add(logo, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0,
				GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
						0, 0, 0), 0, 0));
		// timePanel.add(lUser, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
		// GridBagConstraints.WEST, GridBagConstraints.NONE,
		// new Insets(0, 0, 0, 3), 0, 0));
		// timePanel.add(bLogOut, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0,
		// GridBagConstraints.WEST, GridBagConstraints.NONE,
		// new Insets(0, 0, 0, 0), 0, 0));

		// Create the calendar Panel
		bnAddMeeting.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				bnAddMeetingAction();
			}
		});
		
		bnDeleteMeeting.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				bnDeleteMeetingAction();
			}
		});
		panelCal.setLayout(new GridBagLayout());
		cal = new JCalendar();

		cal.addPropertyChangeListener("calendar", new PropertyChangeListener() {
			@Override
			public void propertyChange(PropertyChangeEvent arg0) {
				CalendarAction();
			}
		});

		panelCal.add(cal, new GridBagConstraints(0, 0, 2, 1, 1.0, 1.0,
				GridBagConstraints.NORTH, GridBagConstraints.BOTH, new Insets(
						0, 0, 0, 0), 0, 0));
		panelCal.add(bnAddMeeting, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0,
				GridBagConstraints.SOUTH, GridBagConstraints.HORIZONTAL,
				new Insets(5, 5, 5, 0), 0, 0));
		panelCal.add(bnDeleteMeeting, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0,
				GridBagConstraints.SOUTH, GridBagConstraints.HORIZONTAL,
				new Insets(5, 5, 5, 0), 0, 0));

		// Create the Meetings Panel
		listAllMeetings = new JList(lm1);
		listAllMeetings.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		listAllMeetings.setLayoutOrientation(JList.VERTICAL);
		listAllMeetings.setVisibleRowCount(-1);
		listAllMeetings.addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				ListAction(e);
			}
		});
		// for (Meeting m : meetings) {
		// lm1.addElement(m);
		// }

		listDayMeetings = new JList(lm2);
		listDayMeetings.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		listDayMeetings.setLayoutOrientation(JList.VERTICAL);
		listDayMeetings.setVisibleRowCount(-1);
		listDayMeetings.addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				ListAction(e);
			}
		});

		tabPane = new JTabbedPane();
		tabPane.addTab("All Meetings", listAllMeetings);
		tabPane.addTab("Day Meetings", listDayMeetings);

		meetingDetails.setContentType("text/html");
		meetingDetails.setText("");

		splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, tabPane,
				meetingDetails);

		// Set panels on main frame
		this.getContentPane().setLayout(new GridBagLayout());
		this.getContentPane().add(
				timePanel,
				new GridBagConstraints(0, 0, 2, 1, 1.0, 0.0,
						GridBagConstraints.NORTH,
						GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0),
						0, 0));

		this.getContentPane().add(
				panelCal,
				new GridBagConstraints(0, 1, 1, 1, 0.1, 1.0,
						GridBagConstraints.WEST, GridBagConstraints.BOTH,
						new Insets(5, 0, 0, 3), 0, 0));

		this.getContentPane().add(
				splitPane,
				new GridBagConstraints(1, 1, 1, 1, 0.9, 1.0,
						GridBagConstraints.EAST, GridBagConstraints.BOTH,
						new Insets(5, 3, 0, 0), 0, 0));

		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.pack();
		this.setSize(800, 450);
		this.setResizable(false);
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		this.setLocation(screen.width / 2 - this.getWidth() / 2, screen.height
				/ 2 - this.getHeight() / 2);
		this.setBackground(Color.WHITE);
		refreshMeetings();
	}

	@SuppressWarnings("unused")
	private void bnDeleteMeetingAction() {
		if(selectedMeeting != null){
			if(JOptionPane.showConfirmDialog(this, "Are you sure you want to delete " + selectedMeeting,
					"Delete Meeting", JOptionPane.YES_NO_OPTION) == JOptionPane.OK_OPTION)
				try {
					if(!server.deleteMeeting(selectedMeeting, user)){
						Tools.errorMessage("Timeout", "Your session has timed out. please login again.");
						server.logOut(user);
						this.dispose();
						new LoginFenster().setVisible(true);
						return;
					}
					refreshMeetings();
				} catch (RemoteException e) {
					e.printStackTrace();
				}
		}
	}

	private void bnAddUserAction() {
		NewUser newUser = new NewUser(server, user);
		newUser.setVisible(true);
	}

	private void bnAddMeetingAction() {
		Calendar c = Calendar.getInstance();
		if (selectedDate != null)
			c.setTime(selectedDate);
		// String date = c.get(Calendar.DAY_OF_MONTH) + "." +
		// c.get(Calendar.MONTH) + "." + c.get(Calendar.YEAR);
		NewMeeting meeting = new NewMeeting(this, c.getTime(), server, user);
		meeting.setVisible(true);
		refreshMeetings();
	}

	@SuppressWarnings({ "unchecked", "unused" })
	private void refreshMeetings() {
		try {
			meetings = server.getMeetings(user);
			if (meetings != null) {
				lm1.clear();
				Date[] meetingDates = new Date[meetings.size()];
				for (int i = 0; i < meetings.size(); i++) {
					lm1.addElement(meetings.get(i));
					meetingDates[i] = meetings.get(i).getDate();
				}
				cal.getDayChooser().setMeetings(meetingDates);
				cal.invalidate();
				selectedMeeting = null;
				bnDeleteMeeting.setEnabled(false);
			}
			else{
				Tools.errorMessage("Timeout", "Your session has timed out. please login again.");
				server.logOut(user);
				this.dispose();
				new LoginFenster().setVisible(true);
				return;
			}
		} catch (RemoteException e) {
			Tools.errorMessage("Error", e.getStackTrace().toString());
		}
	}

	@SuppressWarnings("unchecked")
	private void CalendarAction() {
		selectedDate = cal.getDate();
		Calendar c1 = Calendar.getInstance();
		c1.setTime(selectedDate);
		Calendar c2 = Calendar.getInstance();
		lm2.clear();
		if (meetings != null) {
			for (Meeting m : meetings) {
				c2.setTime(m.getDate());
				if (c1.get(Calendar.DAY_OF_MONTH) == c2
						.get(Calendar.DAY_OF_MONTH)
						&& c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH)
						&& c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR))
					lm2.addElement(m);
			}
		}
//		selectedMeeting = null;
//		bnDeleteMeeting.setEnabled(false);
	}

	@SuppressWarnings("rawtypes")
	private void ListAction(ListSelectionEvent e) {
		JList l = (JList) e.getSource();
		Meeting m = (Meeting) l.getSelectedValue();
		if (m != null) {
			String text = "<b>Meeting Name:</b> " + m.getName();
			text += "<br /><b>Date:</b> " + m.getDate().toString();
			text += "<br /><b>Location:</b> " + m.getLocation();
			text += "<br /><b>Details:</b> " + m.getDetails();
			meetingDetails.setText(text);
			selectedMeeting = m;
			if(user.getPermission())
				bnDeleteMeeting.setEnabled(true);
		}
	}

	private void bLogOutAction() {
		Object[] options = { "Yes", "No" };
		String Title = "Log Out";
		String Text = "Are you sure you want to end this session?";
		int res = JOptionPane.showOptionDialog(null, Text, Title,
				JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null,
				options, options[0]);
		if (res == JOptionPane.YES_OPTION) {
			try {
				server.logOut(user);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
			this.dispose();
			new LoginFenster().setVisible(true);
		}
	}

	@Override
	protected void processWindowEvent(WindowEvent arg0) {
		super.processWindowEvent(arg0);
		try {
			server.logOut(user);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}
	
	protected ImageIcon createImageIcon(String path) {
		java.net.URL imgURL = getClass().getResource(path);
		if (imgURL != null) {
			return new ImageIcon(imgURL);
		} else {
			System.err.println("Couldn't find file: " + path);
			return null;
		}
	}

	// public static void main(String[] args) {
	// HauptFenster haupt;
	// // haupt = new HauptFenster(new User("test", "test", true));
	// // haupt = new HauptFenster("test", false);
	// // haupt.setVisible(true);
	//
	// }

}
